<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>多功能文本编辑器 - 任务6完成版</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f5f5f5;
            height: 100vh;
            overflow: hidden;
        }
        
        .editor-container {
            display: flex;
            flex-direction: column;
            height: 100vh;
            background: white;
            box-shadow: 0 0 20px rgba(0,0,0,0.1);
        }
        
        .editor-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 15px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        
        .editor-title {
            font-size: 1.5em;
            font-weight: 600;
        }
        
        .editor-status {
            display: flex;
            gap: 20px;
            font-size: 0.9em;
            opacity: 0.9;
        }
        
        .status-item {
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .status-indicator {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: #4CAF50;
        }
        
        .status-indicator.saving {
            background: #FF9800;
            animation: pulse 1s infinite;
        }
        
        @keyframes pulse {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.5; }
        }
        
        .toolbar {
            background: #fafafa;
            border-bottom: 1px solid #e0e0e0;
            padding: 10px 20px;
            display: flex;
            gap: 15px;
            align-items: center;
            flex-wrap: wrap;
        }
        
        .toolbar-group {
            display: flex;
            gap: 5px;
            align-items: center;
            padding-right: 15px;
            border-right: 1px solid #e0e0e0;
        }
        
        .toolbar-group:last-child {
            border-right: none;
        }
        
        .toolbar-btn {
            padding: 8px 12px;
            border: 1px solid #ddd;
            background: white;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.2s ease;
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .toolbar-btn:hover {
            background: #f0f0f0;
            border-color: #ccc;
        }
        
        .toolbar-btn.active {
            background: #667eea;
            color: white;
            border-color: #667eea;
        }
        
        .toolbar-btn:disabled {
            opacity: 0.5;
            cursor: not-allowed;
            background: #f9f9f9;
        }
        
        .toolbar-btn:disabled:hover {
            background: #f9f9f9;
            border-color: #ddd;
        }
        
        .toolbar-select {
            padding: 6px 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background: white;
            font-size: 14px;
            cursor: pointer;
            transition: all 0.2s ease;
        }
        
        .toolbar-select:hover {
            border-color: #ccc;
        }
        
        .toolbar-select:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
        }
        
        .editor-main {
            display: flex;
            flex: 1;
            overflow: hidden;
        }
        
        .editor-content {
            flex: 1;
            display: flex;
            flex-direction: column;
            position: relative;
        }
        
        .editor-workspace {
            flex: 1;
            position: relative;
            overflow: hidden;
        }
        
        .editor-textarea {
            width: 100%;
            height: 100%;
            border: none;
            outline: none;
            padding: 20px;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 14px;
            line-height: 1.6;
            resize: none;
            background: white;
            white-space: pre;
            overflow-x: auto;
            transition: all 0.2s ease;
        }
        
        .editor-footer {
            background: #f5f5f5;
            border-top: 1px solid #e0e0e0;
            padding: 8px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 12px;
            color: #666;
        }
        
        .footer-left {
            display: flex;
            gap: 20px;
        }
        
        .footer-right {
            display: flex;
            gap: 20px;
        }
        
        .context-menu {
            position: fixed;
            background: white;
            border: 1px solid #ddd;
            border-radius: 6px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            z-index: 1000;
            min-width: 150px;
            padding: 5px 0;
        }
        
        .context-menu-item {
            padding: 8px 15px;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 10px;
            font-size: 14px;
            transition: background 0.2s ease;
        }
        
        .context-menu-item:hover {
            background: #f0f0f0;
        }
        
        .context-menu-item.disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }
        
        .context-menu-divider {
            height: 1px;
            background: #e0e0e0;
            margin: 5px 0;
        }
        
        .shortcut {
            margin-left: auto;
            font-size: 12px;
            color: #999;
        }
        
        /* 查找替换面板样式 */
        .search-replace {
            position: absolute;
            top: 10px;
            right: 10px;
            background: white;
            border: 1px solid #ddd;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 8px 24px rgba(0,0,0,0.15);
            z-index: 500;
            min-width: 350px;
            max-width: 400px;
        }
        
        .search-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid #eee;
        }
        
        .search-header h4 {
            margin: 0;
            color: #333;
            font-size: 16px;
        }
        
        .close-btn {
            background: none;
            border: none;
            font-size: 20px;
            cursor: pointer;
            color: #999;
            padding: 0;
            width: 24px;
            height: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 4px;
        }
        
        .close-btn:hover {
            background: #f0f0f0;
            color: #666;
        }
        
        .search-inputs {
            display: flex;
            flex-direction: column;
            gap: 10px;
            margin-bottom: 15px;
        }
        
        .search-input-group {
            display: flex;
            gap: 8px;
            align-items: center;
        }
        
        .search-input {
            flex: 1;
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
        }
        
        .search-input:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
        }
        
        .search-btn {
            padding: 8px 12px;
            border: 1px solid #ddd;
            background: white;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
            transition: all 0.2s ease;
        }
        
        .search-btn:hover {
            background: #f0f0f0;
        }
        
        .search-btn.primary {
            background: #667eea;
            color: white;
            border-color: #667eea;
        }
        
        .search-btn.primary:hover {
            background: #5a6fd8;
        }
        
        .search-options {
            display: flex;
            gap: 15px;
            margin-bottom: 15px;
            font-size: 13px;
        }
        
        .search-option {
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .search-option input[type="checkbox"] {
            margin: 0;
        }
        
        .search-actions {
            display: flex;
            gap: 8px;
            justify-content: flex-end;
        }
        
        .search-status {
            background: #e3f2fd;
            border: 1px solid #bbdefb;
            border-radius: 4px;
            padding: 8px;
            margin-bottom: 10px;
            font-size: 12px;
            color: #0d47a1;
            text-align: center;
        }
        
        /* 字数统计面板样式 - 任务6新增 */
        .stats-panel {
            position: absolute;
            top: 10px;
            left: 10px;
            background: white;
            border: 1px solid #ddd;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 8px 24px rgba(0,0,0,0.15);
            z-index: 500;
            min-width: 300px;
            max-width: 400px;
        }
        
        .stats-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid #eee;
        }
        
        .stats-section {
            margin-bottom: 15px;
        }
        
        .stats-section h5 {
            margin: 0 0 10px 0;
            color: #333;
            font-size: 14px;
            font-weight: 600;
        }
        
        .stats-item {
            display: flex;
            justify-content: space-between;
            padding: 5px 0;
            font-size: 13px;
            border-bottom: 1px solid #f5f5f5;
        }
        
        .stats-item:last-child {
            border-bottom: none;
        }
        
        .stats-item span:first-child {
            color: #666;
        }
        
        .stats-item span:last-child {
            font-weight: 600;
            color: #333;
        }
        
        /* 模态框样式 */
        .modal-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.5);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 2000;
        }
        
        .modal {
            background: white;
            border-radius: 8px;
            padding: 20px;
            min-width: 300px;
            max-width: 500px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
        }
        
        .modal-header {
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid #eee;
        }
        
        .modal-header h3 {
            margin: 0;
            color: #333;
        }
        
        .modal-content {
            margin-bottom: 20px;
        }
        
        .modal-input {
            width: 100%;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
            margin-top: 10px;
        }
        
        .modal-input:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
        }
        
        .modal-actions {
            display: flex;
            gap: 10px;
            justify-content: flex-end;
        }
        
        .modal-btn {
            padding: 10px 20px;
            border: 1px solid #ddd;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.2s ease;
        }
        
        .modal-btn.primary {
            background: #667eea;
            color: white;
            border-color: #667eea;
        }
        
        .modal-btn.primary:hover {
            background: #5a6fd8;
        }
        
        .modal-btn:hover {
            background: #f0f0f0;
        }
        
        .drag-overlay {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(102, 126, 234, 0.1);
            border: 3px dashed #667eea;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.2em;
            color: #667eea;
            font-weight: 600;
            z-index: 1000;
        }
        
        .toast {
            position: fixed;
            top: 20px;
            right: 20px;
            background: #4CAF50;
            color: white;
            padding: 12px 20px;
            border-radius: 6px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            z-index: 3000;
            animation: slideInRight 0.3s ease;
        }
        
        .toast.error {
            background: #f44336;
        }
        
        .toast.warning {
            background: #ff9800;
        }
        
        @keyframes slideInRight {
            from {
                opacity: 0;
                transform: translateX(100%);
            }
            to {
                opacity: 1;
                transform: translateX(0);
            }
        }
        
        /* 任务完成提示样式 */
        .task-completed {
            background: #d4edda;
            border: 1px solid #c3e6cb;
            border-radius: 4px;
            padding: 10px;
            margin: 10px;
            font-size: 12px;
            color: #155724;
        }
        
        .task-completed strong {
            color: #0f5132;
        }
        
        /* 全屏模式样式 */
        .fullscreen-mode {
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            z-index: 9999;
            background: white;
        }
        
        .fullscreen-mode .editor-container {
            height: 100vh;
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="editor-container" :class="{ 'fullscreen-mode': isFullscreen }">
            <!-- 编辑器头部 -->
            <div class="editor-header">
                <div class="editor-title">多功能文本编辑器 - 任务6完成版</div>
                <div class="editor-status">
                    <div class="status-item">
                        <div class="status-indicator" :class="{ saving: isSaving }"></div>
                        <span>{{ saveStatus }}</span>
                    </div>
                    <div class="status-item">
                        <span>{{ fontSize }}px {{ fontFamily }}</span>
                    </div>
                    <div class="status-item" v-if="wordWrap">
                        <span>自动换行</span>
                    </div>
                    <div class="status-item" v-if="isFullscreen">
                        <span>全屏模式</span>
                    </div>
                    <div class="status-item" v-if="totalMatches > 0">
                        <span>{{ currentMatchIndex + 1 }}/{{ totalMatches }}</span>
                    </div>
                    <div class="status-item">
                        <span>{{ currentTime }}</span>
                    </div>
                </div>
            </div>
            
            <!-- 工具栏 -->
            <div class="toolbar">
                <div class="toolbar-group">
                    <!-- 任务1: 工具栏按钮点击事件 - 已完成 -->
                    <div class="task-completed">
                        <strong>任务1已完成:</strong> 文件操作功能
                    </div>
                    <button class="toolbar-btn" @click="newFile" title="新建文件 (Ctrl+N)">
                        📄 新建
                    </button>
                    <button class="toolbar-btn" @click="openFile" title="打开文件 (Ctrl+O)">
                        📁 打开
                    </button>
                    <button class="toolbar-btn" @click="saveFile" title="保存文件 (Ctrl+S)">
                        💾 保存
                    </button>
                    <button class="toolbar-btn" @click="saveAsFile" title="另存为 (Ctrl+Shift+S)">
                        📋 另存为
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <!-- 任务2: 撤销/重做功能 - 已完成 -->
                    <div class="task-completed">
                        <strong>任务2已完成:</strong> 撤销/重做功能
                    </div>
                    <button 
                        class="toolbar-btn" 
                        @click="undo" 
                        :disabled="!canUndo"
                        title="撤销 (Ctrl+Z)"
                    >
                        ↶ 撤销
                    </button>
                    <button 
                        class="toolbar-btn" 
                        @click="redo" 
                        :disabled="!canRedo"
                        title="重做 (Ctrl+Y)"
                    >
                        ↷ 重做
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <!-- 任务3: 编辑操作功能 - 已完成 -->
                    <div class="task-completed">
                        <strong>任务3已完成:</strong> 编辑操作功能
                    </div>
                    <button 
                        class="toolbar-btn" 
                        @click="cut" 
                        :disabled="!selectedText"
                        title="剪切 (Ctrl+X)"
                    >
                        ✂️ 剪切
                    </button>
                    <button 
                        class="toolbar-btn" 
                        @click="copy" 
                        :disabled="!selectedText"
                        title="复制 (Ctrl+C)"
                    >
                        📋 复制
                    </button>
                    <button 
                        class="toolbar-btn" 
                        @click="paste" 
                        title="粘贴 (Ctrl+V)"
                    >
                        📌 粘贴
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <!-- 任务4: 格式设置功能 - 已完成 -->
                    <div class="task-completed">
                        <strong>任务4已完成:</strong> 格式设置功能
                    </div>
                    <select 
                        class="toolbar-select" 
                        v-model="fontSize" 
                        @change="updateFontSize"
                        title="字体大小"
                    >
                        <option value="12">12px</option>
                        <option value="14">14px</option>
                        <option value="16">16px</option>
                        <option value="18">18px</option>
                        <option value="20">20px</option>
                        <option value="24">24px</option>
                    </select>
                    
                    <select 
                        class="toolbar-select" 
                        v-model="fontFamily" 
                        @change="updateFontFamily"
                        title="字体类型"
                    >
                        <option value="Consolas">Consolas</option>
                        <option value="Monaco">Monaco</option>
                        <option value="Courier New">Courier New</option>
                        <option value="Arial">Arial</option>
                        <option value="Microsoft YaHei">微软雅黑</option>
                    </select>
                    
                    <button 
                        class="toolbar-btn" 
                        :class="{ active: wordWrap }"
                        @click="toggleWordWrap" 
                        title="自动换行"
                    >
                        📝 换行
                    </button>
                    
                    <button 
                        class="toolbar-btn" 
                        :class="{ active: isFullscreen }"
                        @click="toggleFullscreen" 
                        title="全屏模式 (F11)"
                    >
                        🔳 全屏
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <!-- 任务5: 查找替换功能 - 已完成 -->
                    <div class="task-completed">
                        <strong>任务5已完成:</strong> 查找替换功能
                    </div>
                    <button 
                        class="toolbar-btn" 
                        :class="{ active: showSearchPanel }"
                        @click="toggleSearch" 
                        title="查找替换 (Ctrl+F)"
                    >
                        🔍 查找
                    </button>
                    <button 
                        class="toolbar-btn" 
                        @click="selectAll" 
                        title="全选 (Ctrl+A)"
                    >
                        📄 全选
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <!-- 任务6: 字数统计功能 - 已完成 -->
                    <div class="task-completed">
                        <strong>任务6已完成:</strong> 字数统计功能
                    </div>
                    <button 
                        class="toolbar-btn" 
                        :class="{ active: showStatsPanel }"
                        @click="toggleStatsPanel" 
                        title="字数统计 (Ctrl+I)"
                    >
                        📊 统计
                    </button>
                </div>
            </div>
            
            <!-- 编辑器主体 -->
            <div class="editor-main">
                <div class="editor-content">
                    <div class="editor-workspace">
                        <textarea 
                            ref="textarea"
                            class="editor-textarea"
                            v-model="content"
                            @input="handleInput"
                            @keydown="handleKeydown"
                            @scroll="handleScroll"
                            @select="updateSelection"
                            @mouseup="updateSelection"
                            @keyup="updateSelection"
                            :style="{
                                fontSize: fontSize + 'px',
                                fontFamily: fontFamily,
                                whiteSpace: wordWrap ? 'pre-wrap' : 'pre'
                            }"
                            placeholder="开始输入您的文档内容..."
                        ></textarea>
                        
                        <!-- 拖拽覆盖层 -->
                        <div v-if="isDragging" class="drag-overlay">
                            📁 拖拽文件到此处打开
                        </div>
                        
                        <!-- 查找替换面板 -->
                        <div v-if="showSearchPanel" class="search-replace">
                            <div class="search-header">
                                <h4>查找和替换</h4>
                                <button class="close-btn" @click="toggleSearch">×</button>
                            </div>
                            
                            <div v-if="totalMatches > 0" class="search-status">
                                找到 {{ totalMatches }} 个匹配项，当前第 {{ currentMatchIndex + 1 }} 个
                            </div>
                            <div v-else-if="searchText && totalMatches === 0" class="search-status">
                                未找到匹配项
                            </div>
                            
                            <div class="search-inputs">
                                <div class="search-input-group">
                                    <input 
                                        type="text" 
                                        class="search-input" 
                                        v-model="searchText" 
                                        @input="performSearch"
                                        @keydown.enter="findNext"
                                        @keydown.escape="toggleSearch"
                                        placeholder="查找内容"
                                        ref="searchInput"
                                    >
                                    <button class="search-btn" @click="findPrevious" :disabled="totalMatches === 0">↑</button>
                                    <button class="search-btn" @click="findNext" :disabled="totalMatches === 0">↓</button>
                                </div>
                                
                                <div class="search-input-group">
                                    <input 
                                        type="text" 
                                        class="search-input" 
                                        v-model="replaceText" 
                                        @keydown.enter="replaceNext"
                                        placeholder="替换为"
                                    >
                                    <button class="search-btn" @click="replaceNext" :disabled="totalMatches === 0">替换</button>
                                    <button class="search-btn" @click="replaceAll" :disabled="totalMatches === 0">全部替换</button>
                                </div>
                            </div>
                            
                            <div class="search-options">
                                <div class="search-option">
                                    <input type="checkbox" id="caseSensitive" v-model="caseSensitive" @change="performSearch">
                                    <label for="caseSensitive">区分大小写</label>
                                </div>
                                <div class="search-option">
                                    <input type="checkbox" id="useRegex" v-model="useRegex" @change="performSearch">
                                    <label for="useRegex">正则表达式</label>
                                </div>
                            </div>
                        </div>
                        
                        <!-- 字数统计面板 - 任务6新增 -->
                        <div v-if="showStatsPanel" class="stats-panel">
                            <div class="stats-header">
                                <h4>文档统计</h4>
                                <button class="close-btn" @click="toggleStatsPanel">×</button>
                            </div>
                            
                            <div class="stats-content">
                                <div class="stats-section">
                                    <h5>全文统计</h5>
                                    <div class="stats-item">
                                        <span>字符数（含空格）:</span>
                                        <span>{{ formatNumber(documentStats.characters) }}</span>
                                    </div>
                                    <div class="stats-item">
                                        <span>字符数（不含空格）:</span>
                                        <span>{{ formatNumber(documentStats.charactersNoSpaces) }}</span>
                                    </div>
                                    <div class="stats-item">
                                        <span>单词数:</span>
                                        <span>{{ formatNumber(documentStats.words) }}</span>
                                    </div>
                                    <div class="stats-item">
                                        <span>行数:</span>
                                        <span>{{ documentStats.lines }}</span>
                                    </div>
                                    <div class="stats-item">
                                        <span>非空行数:</span>
                                        <span>{{ documentStats.nonEmptyLines }}</span>
                                    </div>
                                    <div class="stats-item">
                                        <span>段落数:</span>
                                        <span>{{ documentStats.paragraphs }}</span>
                                    </div>
                                </div>
                                
                                <div v-if="selectedText" class="stats-section">
                                    <h5>选中文本统计</h5>
                                    <div class="stats-item">
                                        <span>字符数:</span>
                                        <span>{{ formatNumber(selectionStats.characters) }}</span>
                                    </div>
                                    <div class="stats-item">
                                        <span>单词数:</span>
                                        <span>{{ formatNumber(selectionStats.words) }}</span>
                                    </div>
                                    <div class="stats-item">
                                        <span>行数:</span>
                                        <span>{{ selectionStats.lines }}</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 编辑器底部状态栏 -->
            <div class="editor-footer">
                <div class="footer-left">
                    <span>行 {{ cursorPosition.line }}, 列 {{ cursorPosition.column }}</span>
                    <span v-if="selectedText">选中 {{ selectionStats.characters }} 字符</span>
                    <span v-else>字符数: {{ formatNumber(documentStats.characters) }}</span>
                    <span>单词数: {{ formatNumber(documentStats.words) }}</span>
                    <span>行数: {{ documentStats.lines }}</span>
                    <span v-if="historyIndex >= 0">历史: {{ historyIndex + 1 }}/{{ history.length }}</span>
                </div>
                <div class="footer-right">
                    <span>编码: UTF-8</span>
                    <span>{{ currentFileName || '未命名文档' }}</span>
                </div>
            </div>
            
            <!-- 右键菜单 -->
            <div v-if="showContextMenu" class="context-menu" :style="{ left: contextMenuPosition.x + 'px', top: contextMenuPosition.y + 'px' }">
                <div class="context-menu-item" @click="cut" :class="{ disabled: !selectedText }">
                    ✂️ 剪切
                    <span class="shortcut">Ctrl+X</span>
                </div>
                <div class="context-menu-item" @click="copy" :class="{ disabled: !selectedText }">
                    📋 复制
                    <span class="shortcut">Ctrl+C</span>
                </div>
                <div class="context-menu-item" @click="paste">
                    📌 粘贴
                    <span class="shortcut">Ctrl+V</span>
                </div>
                <div class="context-menu-divider"></div>
                <div class="context-menu-item" @click="selectAll">
                    📄 全选
                    <span class="shortcut">Ctrl+A</span>
                </div>
                <div class="context-menu-divider"></div>
                <div class="context-menu-item" @click="toggleSearch">
                    🔍 查找替换
                    <span class="shortcut">Ctrl+F</span>
                </div>
                <div class="context-menu-item" @click="toggleStatsPanel">
                    📊 字数统计
                    <span class="shortcut">Ctrl+I</span>
                </div>
            </div>
        </div>
        
        <!-- 模态框 -->
        <div v-if="showModal" class="modal-overlay" @click="closeModal">
            <div class="modal" @click.stop>
                <div class="modal-header">
                    <h3>{{ modalTitle }}</h3>
                </div>
                <div class="modal-content">
                    <p>{{ modalMessage }}</p>
                    <input 
                        v-if="modalType === 'prompt'" 
                        type="text" 
                        class="modal-input" 
                        v-model="modalInput" 
                        @keydown.enter="confirmModal"
                        ref="modalInputRef"
                    >
                </div>
                <div class="modal-actions">
                    <button class="modal-btn" @click="closeModal">取消</button>
                    <button class="modal-btn primary" @click="confirmModal">确定</button>
                </div>
            </div>
        </div>
        
        <!-- Toast 通知 -->
        <div v-if="showToastMessage" class="toast" :class="toastType">
            {{ toastMessage }}
        </div>
    </div>
    
    <script>
        const { createApp, ref, computed, onMounted, onUnmounted, nextTick } = Vue;
        
        createApp({
            setup() {
                // 基础响应式数据
                const content = ref('');
                const currentFileName = ref('');
                const saveStatus = ref('已保存');
                const isSaving = ref(false);
                const currentTime = ref('');
                const textarea = ref(null);
                
                // 历史记录相关 - 任务2
                const history = ref([]);
                const historyIndex = ref(-1);
                const lastSavedContent = ref('');
                
                // 选择和光标相关 - 任务3
                const selectedText = ref('');
                const selectionStart = ref(0);
                const selectionEnd = ref(0);
                const selectionLength = ref(0);
                const cursorPosition = ref({ line: 1, column: 1 });
                
                // 格式设置相关 - 任务4
                const fontSize = ref(14);
                const fontFamily = ref('Consolas');
                const wordWrap = ref(false);
                const isFullscreen = ref(false);
                
                // 查找替换相关 - 任务5
                const showSearchPanel = ref(false);
                const searchText = ref('');
                const replaceText = ref('');
                const caseSensitive = ref(false);
                const useRegex = ref(false);
                const searchMatches = ref([]);
                const currentMatchIndex = ref(-1);
                const searchInput = ref(null);
                
                // 字数统计相关 - 任务6新增
                const showStatsPanel = ref(false);
                const selectedStats = ref({
                    characters: 0,
                    charactersNoSpaces: 0,
                    words: 0,
                    lines: 0,
                    paragraphs: 0
                });
                
                // 界面状态
                const showContextMenu = ref(false);
                const contextMenuPosition = ref({ x: 0, y: 0 });
                const showModal = ref(false);
                const modalTitle = ref('');
                const modalMessage = ref('');
                const modalType = ref('alert');
                const modalInput = ref('');
                const modalInputRef = ref(null);
                const modalResolve = ref(null);
                const showToastMessage = ref(false);
                const toastMessage = ref('');
                const toastType = ref('success');
                const isDragging = ref(false);
                
                // 计算属性
                const canUndo = computed(() => historyIndex.value > 0);
                const canRedo = computed(() => historyIndex.value < history.value.length - 1);
                const totalMatches = computed(() => searchMatches.value.length);
                
                // 字数统计计算属性 - 任务6新增
                const documentStats = computed(() => {
                    return calculateStats(content.value);
                });
                
                const selectionStats = computed(() => {
                    return calculateStats(selectedText.value);
                });
                
                // 字数统计函数 - 任务6新增
                const calculateStats = (text) => {
                    if (!text) {
                        return {
                            characters: 0,
                            charactersNoSpaces: 0,
                            words: 0,
                            lines: 0,
                            nonEmptyLines: 0,
                            paragraphs: 0
                        };
                    }
                    
                    // 字符数统计
                    const characters = text.length;
                    const charactersNoSpaces = text.replace(/\s/g, '').length;
                    
                    // 行数统计
                    const lines = text.split('\n').length;
                    const nonEmptyLines = text.split('\n').filter(line => line.trim() !== '').length;
                    
                    // 单词数统计（支持中英文）
                    const words = countWords(text);
                    
                    // 段落数统计
                    const paragraphs = text.split(/\n\s*\n/).filter(p => p.trim() !== '').length;
                    
                    return {
                        characters,
                        charactersNoSpaces,
                        words,
                        lines,
                        nonEmptyLines,
                        paragraphs
                    };
                };
                
                // 单词计数函数 - 任务6新增
                const countWords = (text) => {
                    if (!text.trim()) return 0;
                    
                    // 移除多余空白字符
                    const cleanText = text.trim().replace(/\s+/g, ' ');
                    
                    // 分离中文字符和英文单词
                    const chineseChars = cleanText.match(/[\u4e00-\u9fa5]/g) || [];
                    const englishWords = cleanText.replace(/[\u4e00-\u9fa5]/g, ' ')
                                                 .trim()
                                                 .split(/\s+/)
                                                 .filter(word => word.length > 0);
                    
                    return chineseChars.length + englishWords.length;
                };
                
                // 格式化数字显示 - 任务6新增
                const formatNumber = (num) => {
                    return num.toLocaleString();
                };
                
                // 切换统计面板 - 任务6新增
                const toggleStatsPanel = () => {
                    showStatsPanel.value = !showStatsPanel.value;
                    if (showStatsPanel.value) {
                        showToast('统计面板已打开', 'success');
                    } else {
                        showToast('统计面板已关闭', 'success');
                    }
                };
                
                // 文件操作函数 - 任务1
                const newFile = () => {
                    if (content.value && content.value !== lastSavedContent.value) {
                        showConfirm('新建文件', '当前文档有未保存的更改，是否继续？').then((confirmed) => {
                            if (confirmed) {
                                content.value = '';
                                currentFileName.value = '';
                                saveStatus.value = '已保存';
                                resetHistory();
                                showToast('新建文件成功', 'success');
                            }
                        });
                    } else {
                        content.value = '';
                        currentFileName.value = '';
                        saveStatus.value = '已保存';
                        resetHistory();
                        showToast('新建文件成功', 'success');
                    }
                };
                
                const openFile = () => {
                    const input = document.createElement('input');
                    input.type = 'file';
                    input.accept = '.txt,.md,.js,.html,.css,.json';
                    input.onchange = (e) => {
                        const file = e.target.files[0];
                        if (file) {
                            const reader = new FileReader();
                            reader.onload = (e) => {
                                content.value = e.target.result;
                                currentFileName.value = file.name;
                                saveStatus.value = '已保存';
                                lastSavedContent.value = content.value;
                                resetHistory();
                                showToast(`文件 "${file.name}" 打开成功`, 'success');
                            };
                            reader.readAsText(file);
                        }
                    };
                    input.click();
                };
                
                const saveFile = () => {
                    if (currentFileName.value) {
                        downloadFile(content.value, currentFileName.value);
                    } else {
                        saveAsFile();
                    }
                };
                
                const saveAsFile = () => {
                    showPrompt('另存为', '请输入文件名:', currentFileName.value || 'document.txt').then((filename) => {
                        if (filename) {
                            downloadFile(content.value, filename);
                            currentFileName.value = filename;
                        }
                    });
                };
                
                const downloadFile = (content, filename) => {
                    isSaving.value = true;
                    saveStatus.value = '保存中...';
                    
                    setTimeout(() => {
                        const blob = new Blob([content], { type: 'text/plain' });
                        const url = URL.createObjectURL(blob);
                        const a = document.createElement('a');
                        a.href = url;
                        a.download = filename;
                        a.click();
                        URL.revokeObjectURL(url);
                        
                        isSaving.value = false;
                        saveStatus.value = '已保存';
                        lastSavedContent.value = content;
                        showToast(`文件 "${filename}" 保存成功`, 'success');
                    }, 500);
                };
                
                // 历史记录管理 - 任务2
                const saveToHistory = (newContent) => {
                    if (history.value.length === 0 || history.value[historyIndex.value] !== newContent) {
                        // 如果当前不在历史记录的末尾，删除后面的记录
                        if (historyIndex.value < history.value.length - 1) {
                            history.value = history.value.slice(0, historyIndex.value + 1);
                        }
                        
                        history.value.push(newContent);
                        historyIndex.value = history.value.length - 1;
                        
                        // 限制历史记录数量
                        if (history.value.length > 100) {
                            history.value.shift();
                            historyIndex.value--;
                        }
                    }
                };
                
                const resetHistory = () => {
                    history.value = [content.value];
                    historyIndex.value = 0;
                };
                
                const undo = () => {
                    if (canUndo.value) {
                        historyIndex.value--;
                        content.value = history.value[historyIndex.value];
                        showToast('撤销成功', 'success');
                    }
                };
                
                const redo = () => {
                    if (canRedo.value) {
                        historyIndex.value++;
                        content.value = history.value[historyIndex.value];
                        showToast('重做成功', 'success');
                    }
                };
                
                // 编辑操作 - 任务3
                const updateSelection = () => {
                    if (textarea.value) {
                        const element = textarea.value;
                        selectionStart.value = element.selectionStart;
                        selectionEnd.value = element.selectionEnd;
                        selectedText.value = content.value.substring(
                            element.selectionStart, 
                            element.selectionEnd
                        );
                        selectionLength.value = selectedText.value.length;
                        
                        // 更新光标位置
                        const beforeCursor = content.value.substring(0, element.selectionStart);
                        const lines = beforeCursor.split('\n');
                        cursorPosition.value = {
                            line: lines.length,
                            column: lines[lines.length - 1].length + 1
                        };
                    }
                };
                
                const cut = async () => {
                    if (selectedText.value) {
                        try {
                            await navigator.clipboard.writeText(selectedText.value);
                            const start = selectionStart.value;
                            const end = selectionEnd.value;
                            content.value = content.value.substring(0, start) + content.value.substring(end);
                            
                            // 设置光标位置
                            nextTick(() => {
                                if (textarea.value) {
                                    textarea.value.setSelectionRange(start, start);
                                    textarea.value.focus();
                                }
                            });
                            
                            showToast('剪切成功', 'success');
                        } catch (err) {
                            // 降级方案
                            document.execCommand('cut');
                            showToast('剪切成功', 'success');
                        }
                    }
                };
                
                const copy = async () => {
                    if (selectedText.value) {
                        try {
                            await navigator.clipboard.writeText(selectedText.value);
                            showToast('复制成功', 'success');
                        } catch (err) {
                            // 降级方案
                            document.execCommand('copy');
                            showToast('复制成功', 'success');
                        }
                    }
                };
                
                const paste = async () => {
                    try {
                        const text = await navigator.clipboard.readText();
                        const start = selectionStart.value;
                        const end = selectionEnd.value;
                        const newContent = content.value.substring(0, start) + text + content.value.substring(end);
                        content.value = newContent;
                        
                        // 设置光标位置到粘贴内容的末尾
                        const newCursorPos = start + text.length;
                        nextTick(() => {
                            if (textarea.value) {
                                textarea.value.setSelectionRange(newCursorPos, newCursorPos);
                                textarea.value.focus();
                            }
                        });
                        
                        showToast('粘贴成功', 'success');
                    } catch (err) {
                        // 降级方案
                        document.execCommand('paste');
                        showToast('粘贴成功', 'success');
                    }
                };
                
                const selectAll = () => {
                    if (textarea.value) {
                        textarea.value.select();
                        updateSelection();
                        showToast('全选成功', 'success');
                    }
                };
                
                // 格式设置 - 任务4
                const updateFontSize = () => {
                    localStorage.setItem('editor-font-size', fontSize.value);
                    showToast(`字体大小已设置为 ${fontSize.value}px`, 'success');
                };
                
                const updateFontFamily = () => {
                    localStorage.setItem('editor-font-family', fontFamily.value);
                    showToast(`字体已设置为 ${fontFamily.value}`, 'success');
                };
                
                const toggleWordWrap = () => {
                    wordWrap.value = !wordWrap.value;
                    localStorage.setItem('editor-word-wrap', wordWrap.value);
                    showToast(wordWrap.value ? '自动换行已开启' : '自动换行已关闭', 'success');
                };
                
                const toggleFullscreen = () => {
                    if (!document.fullscreenElement) {
                        document.documentElement.requestFullscreen();
                        isFullscreen.value = true;
                        showToast('已进入全屏模式', 'success');
                    } else {
                        document.exitFullscreen();
                        isFullscreen.value = false;
                        showToast('已退出全屏模式', 'success');
                    }
                };
                
                // 查找替换功能 - 任务5
                const toggleSearch = () => {
                    showSearchPanel.value = !showSearchPanel.value;
                    if (showSearchPanel.value) {
                        nextTick(() => {
                            if (searchInput.value) {
                                searchInput.value.focus();
                            }
                        });
                        showToast('查找面板已打开', 'success');
                    } else {
                        showToast('查找面板已关闭', 'success');
                    }
                };
                
                const performSearch = () => {
                    if (!searchText.value) {
                        searchMatches.value = [];
                        currentMatchIndex.value = -1;
                        return;
                    }
                    
                    try {
                        let flags = 'g';
                        if (!caseSensitive.value) flags += 'i';
                        
                        let pattern;
                        if (useRegex.value) {
                            pattern = new RegExp(searchText.value, flags);
                        } else {
                            // 转义特殊字符
                            const escapedText = searchText.value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
                            pattern = new RegExp(escapedText, flags);
                        }
                        
                        const matches = [];
                        let match;
                        while ((match = pattern.exec(content.value)) !== null) {
                            matches.push({
                                index: match.index,
                                length: match[0].length,
                                text: match[0]
                            });
                            
                            // 防止无限循环
                            if (match[0].length === 0) {
                                pattern.lastIndex++;
                            }
                        }
                        
                        searchMatches.value = matches;
                        currentMatchIndex.value = matches.length > 0 ? 0 : -1;
                        
                        if (matches.length > 0) {
                            highlightMatch(0);
                        }
                    } catch (err) {
                        showToast('搜索表达式错误', 'error');
                        searchMatches.value = [];
                        currentMatchIndex.value = -1;
                    }
                };
                
                const findNext = () => {
                    if (searchMatches.value.length > 0) {
                        currentMatchIndex.value = (currentMatchIndex.value + 1) % searchMatches.value.length;
                        highlightMatch(currentMatchIndex.value);
                    }
                };
                
                const findPrevious = () => {
                    if (searchMatches.value.length > 0) {
                        currentMatchIndex.value = currentMatchIndex.value <= 0 
                            ? searchMatches.value.length - 1 
                            : currentMatchIndex.value - 1;
                        highlightMatch(currentMatchIndex.value);
                    }
                };
                
                const highlightMatch = (index) => {
                    if (index >= 0 && index < searchMatches.value.length) {
                        const match = searchMatches.value[index];
                        if (textarea.value) {
                            textarea.value.setSelectionRange(match.index, match.index + match.length);
                            textarea.value.focus();
                        }
                    }
                };
                
                const replaceNext = () => {
                    if (currentMatchIndex.value >= 0 && currentMatchIndex.value < searchMatches.value.length) {
                        const match = searchMatches.value[currentMatchIndex.value];
                        const newContent = content.value.substring(0, match.index) + 
                                         replaceText.value + 
                                         content.value.substring(match.index + match.length);
                        content.value = newContent;
                        
                        // 重新搜索
                        performSearch();
                        showToast('替换成功', 'success');
                    }
                };
                
                const replaceAll = () => {
                    if (searchMatches.value.length > 0) {
                        const count = searchMatches.value.length;
                        let newContent = content.value;
                        
                        // 从后往前替换，避免索引变化
                        for (let i = searchMatches.value.length - 1; i >= 0; i--) {
                            const match = searchMatches.value[i];
                            newContent = newContent.substring(0, match.index) + 
                                       replaceText.value + 
                                       newContent.substring(match.index + match.length);
                        }
                        
                        content.value = newContent;
                        performSearch();
                        showToast(`已替换 ${count} 处`, 'success');
                    }
                };
                
                // 事件处理
                const handleInput = () => {
                    saveStatus.value = '未保存';
                    
                    // 防抖保存到历史记录
                    clearTimeout(window.saveHistoryTimer);
                    window.saveHistoryTimer = setTimeout(() => {
                        saveToHistory(content.value);
                    }, 1000);
                    
                    // 自动保存
                    clearTimeout(window.autoSaveTimer);
                    window.autoSaveTimer = setTimeout(() => {
                        if (currentFileName.value) {
                            localStorage.setItem('editor-auto-save-' + currentFileName.value, content.value);
                        }
                    }, 5000);
                };
                
                const handleKeydown = (event) => {
                    // 文件操作快捷键
                    if (event.ctrlKey) {
                        switch (event.key.toLowerCase()) {
                            case 'n':
                                event.preventDefault();
                                newFile();
                                break;
                            case 'o':
                                event.preventDefault();
                                openFile();
                                break;
                            case 's':
                                event.preventDefault();
                                if (event.shiftKey) {
                                    saveAsFile();
                                } else {
                                    saveFile();
                                }
                                break;
                            case 'z':
                                event.preventDefault();
                                if (event.shiftKey) {
                                    redo();
                                } else {
                                    undo();
                                }
                                break;
                            case 'y':
                                event.preventDefault();
                                redo();
                                break;
                            case 'f':
                                event.preventDefault();
                                toggleSearch();
                                break;
                            case 'h':
                                event.preventDefault();
                                toggleSearch();
                                break;
                            case 'a':
                                event.preventDefault();
                                selectAll();
                                break;
                            case '=':
                            case '+':
                                event.preventDefault();
                                if (fontSize.value < 24) {
                                    fontSize.value++;
                                    updateFontSize();
                                }
                                break;
                            case '-':
                                event.preventDefault();
                                if (fontSize.value > 8) {
                                    fontSize.value--;
                                    updateFontSize();
                                }
                                break;
                            case 'i':
                                event.preventDefault();
                                toggleStatsPanel();
                                break;
                        }
                    }
                    
                    // 查找面板快捷键
                    if (showSearchPanel.value) {
                        if (event.key === 'Escape') {
                            showSearchPanel.value = false;
                        } else if (event.key === 'F3' || (event.ctrlKey && event.key === 'g')) {
                            event.preventDefault();
                            findNext();
                        } else if (event.shiftKey && event.key === 'F3') {
                            event.preventDefault();
                            findPrevious();
                        }
                    }
                    
                    // 全屏快捷键
                    if (event.key === 'F11') {
                        event.preventDefault();
                        toggleFullscreen();
                    }
                };
                
                const handleSelectionChange = () => {
                    updateSelection();
                };
                
                const handleContextMenu = (event) => {
                    event.preventDefault();
                    contextMenuPosition.value = {
                        x: event.clientX,
                        y: event.clientY
                    };
                    showContextMenu.value = true;
                };
                
                const hideContextMenu = () => {
                    showContextMenu.value = false;
                };
                
                const handleDragOver = (event) => {
                    event.preventDefault();
                    isDragging.value = true;
                };
                
                const handleDragLeave = (event) => {
                    if (!event.currentTarget.contains(event.relatedTarget)) {
                        isDragging.value = false;
                    }
                };
                
                const handleDrop = (event) => {
                    event.preventDefault();
                    isDragging.value = false;
                    
                    const files = event.dataTransfer.files;
                    if (files.length > 0) {
                        const file = files[0];
                        if (file.type.startsWith('text/') || file.name.match(/\.(txt|md|js|html|css|json)$/i)) {
                            const reader = new FileReader();
                            reader.onload = (e) => {
                                content.value = e.target.result;
                                currentFileName.value = file.name;
                                saveStatus.value = '已保存';
                                lastSavedContent.value = content.value;
                                resetHistory();
                                showToast(`文件 "${file.name}" 拖拽打开成功`, 'success');
                            };
                            reader.readAsText(file);
                        } else {
                            showToast('不支持的文件类型', 'error');
                        }
                    }
                };
                
                // 监听器
                const watchContent = () => {
                    // 监听内容变化
                    const stopWatchingContent = Vue.watch(content, (newContent) => {
                        updateSelection();
                    });
                    
                    // 监听搜索文本变化
                    const stopWatchingSearch = Vue.watch([searchText, caseSensitive, useRegex], () => {
                        performSearch();
                    });
                    
                    return () => {
                        stopWatchingContent();
                        stopWatchingSearch();
                    };
                };
                
                // 工具函数
                const updateTime = () => {
                    const now = new Date();
                    currentTime.value = now.toLocaleTimeString('zh-CN', {
                        hour12: false,
                        hour: '2-digit',
                        minute: '2-digit',
                        second: '2-digit'
                    });
                };
                
                const showToast = (message, type = 'success') => {
                    toastMessage.value = message;
                    toastType.value = type;
                    showToastMessage.value = true;
                    
                    setTimeout(() => {
                        showToastMessage.value = false;
                    }, 3000);
                };
                
                const showAlert = (title, message) => {
                    return new Promise((resolve) => {
                        modalTitle.value = title;
                        modalMessage.value = message;
                        modalType.value = 'alert';
                        modalResolve.value = resolve;
                        showModal.value = true;
                    });
                };
                
                const showConfirm = (title, message) => {
                    return new Promise((resolve) => {
                        modalTitle.value = title;
                        modalMessage.value = message;
                        modalType.value = 'confirm';
                        modalResolve.value = resolve;
                        showModal.value = true;
                    });
                };
                
                const showPrompt = (title, message, defaultValue = '') => {
                    return new Promise((resolve) => {
                        modalTitle.value = title;
                        modalMessage.value = message;
                        modalType.value = 'prompt';
                        modalInput.value = defaultValue;
                        modalResolve.value = resolve;
                        showModal.value = true;
                        
                        nextTick(() => {
                            if (modalInputRef.value) {
                                modalInputRef.value.focus();
                                modalInputRef.value.select();
                            }
                        });
                    });
                };
                
                const confirmModal = () => {
                    if (modalResolve.value) {
                        if (modalType.value === 'prompt') {
                            modalResolve.value(modalInput.value);
                        } else if (modalType.value === 'confirm') {
                            modalResolve.value(true);
                        } else {
                            modalResolve.value();
                        }
                    }
                    showModal.value = false;
                };
                
                const cancelModal = () => {
                    if (modalResolve.value) {
                        if (modalType.value === 'confirm') {
                            modalResolve.value(false);
                        } else if (modalType.value === 'prompt') {
                            modalResolve.value(null);
                        }
                    }
                    showModal.value = false;
                };
                
                // 生命周期
                onMounted(() => {
                    // 恢复用户设置
                    const savedFontSize = localStorage.getItem('editor-font-size');
                    if (savedFontSize) {
                        fontSize.value = parseInt(savedFontSize);
                    }
                    
                    const savedFontFamily = localStorage.getItem('editor-font-family');
                    if (savedFontFamily) {
                        fontFamily.value = savedFontFamily;
                    }
                    
                    const savedWordWrap = localStorage.getItem('editor-word-wrap');
                    if (savedWordWrap !== null) {
                        wordWrap.value = savedWordWrap === 'true';
                    }
                    
                    // 初始化历史记录
                    resetHistory();
                    
                    // 更新时间
                    updateTime();
                    const timeInterval = setInterval(updateTime, 1000);
                    
                    // 添加全局事件监听
                    document.addEventListener('keydown', handleKeydown);
                    document.addEventListener('click', hideContextMenu);
                    document.addEventListener('selectionchange', handleSelectionChange);
                    
                    // 添加拖拽事件监听
                    const editorElement = document.querySelector('.editor');
                    if (editorElement) {
                        editorElement.addEventListener('dragover', handleDragOver);
                        editorElement.addEventListener('dragleave', handleDragLeave);
                        editorElement.addEventListener('drop', handleDrop);
                    }
                    
                    // 启动监听器
                    const stopWatching = watchContent();
                    
                    // 清理函数
                    onUnmounted(() => {
                        clearInterval(timeInterval);
                        clearTimeout(window.saveHistoryTimer);
                        clearTimeout(window.autoSaveTimer);
                        document.removeEventListener('keydown', handleKeydown);
                        document.removeEventListener('click', hideContextMenu);
                        document.removeEventListener('selectionchange', handleSelectionChange);
                        
                        if (editorElement) {
                            editorElement.removeEventListener('dragover', handleDragOver);
                            editorElement.removeEventListener('dragleave', handleDragLeave);
                            editorElement.removeEventListener('drop', handleDrop);
                        }
                        
                        stopWatching();
                    });
                });
                
                // 返回所有响应式数据和方法
                return {
                    // 响应式数据
                    content,
                    currentFileName,
                    saveStatus,
                    isSaving,
                    currentTime,
                    textarea,
                    history,
                    historyIndex,
                    selectedText,
                    selectionStart,
                    selectionEnd,
                    selectionLength,
                    cursorPosition,
                    fontSize,
                    fontFamily,
                    wordWrap,
                    isFullscreen,
                    showSearchPanel,
                    searchText,
                    replaceText,
                    caseSensitive,
                    useRegex,
                    searchMatches,
                    currentMatchIndex,
                    searchInput,
                    showStatsPanel,
                    selectedStats,
                    showContextMenu,
                    contextMenuPosition,
                    showModal,
                    modalTitle,
                    modalMessage,
                    modalType,
                    modalInput,
                    modalInputRef,
                    showToastMessage,
                    toastMessage,
                    toastType,
                    isDragging,
                    
                    // 计算属性
                    canUndo,
                    canRedo,
                    totalMatches,
                    documentStats,
                    selectionStats,
                    
                    // 方法
                    newFile,
                    openFile,
                    saveFile,
                    saveAsFile,
                    undo,
                    redo,
                    cut,
                    copy,
                    paste,
                    selectAll,
                    updateFontSize,
                    updateFontFamily,
                    toggleWordWrap,
                    toggleFullscreen,
                    toggleSearch,
                    findNext,
                    findPrevious,
                    replaceNext,
                    replaceAll,
                    toggleStatsPanel,
                    formatNumber,
                    handleInput,
                    handleContextMenu,
                    hideContextMenu,
                    confirmModal,
                    cancelModal
                };
            }
        }).mount('#app');
    </script>
</body>
</html>